package com.edu.stress.test.util;

import lombok.NonNull;
import net.sf.json.JSONObject;
import org.apache.http.*;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.security.cert.X509Certificate;
import java.util.Iterator;

public class HttpUtil {
	
	private static final Logger logger = Logger.getLogger(HttpUtil.class);
	
	
	// max connection number from the http client.
	private static final int HTTPCLIENT_CONNECTION_COUNT = 500;
	// count per route.
	private static final int HTTPCLIENT_MAXPERROUTE_COUNT = 200;
	// connection timeout.
	private static final int HTTPCLIENT_CONNECT_TIMEOUT = 6000;
	// socket timeout.
	private static final int HTTPCLIENT_SOCKET_TIMEOUT = 6000;
	// ����httpclient���ӳ�
	private static PoolingHttpClientConnectionManager httpClientConnectionManager = null;
	/****** ����ģʽ������ʼ ******/
	// ���ʼ��ʱ���Զ�ʵ��������������ģʽ
	private static final HttpUtil httpUtil = new HttpUtil();

	/**
	 * 
	 * ��������getHttpUtilInstance �����������ľ�̬����������HttpUtil��ʵ��
	 * 
	 * @return
	 */
	public static HttpUtil getHttpUtilInstance() {
		return httpUtil;
	}

	/****** ����ģʽ�������� ******/
	/**
	 * ˽�еĹ��캯��
	 */
	private HttpUtil() {
		// ��ʼ��httpClient
		initHttpClient();
	}

	/**
	 * post the json request.
	 * 
	 * @param url
	 * @param jsonRequest
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String postJson(@NonNull final String url, @NonNull final String jsonRequest) {
		String body = null;
		int statusCode = 0;
		// 建立一个NameValuePair数组，用于存储欲传送的参数
		HttpPost post = new HttpPost(url);
		post.addHeader("Content-type", "application/json; charset=utf-8");
		post.addHeader("Accept", "application/json");
		post.setEntity(new StringEntity(jsonRequest, Charset.forName("UTF-8")));
        
		HttpResponse response;
		try {
			response = getHttpClient().execute(post);
			statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != HttpStatus.SC_OK) {
				logger.error("response.getStatusLine:" + response.getStatusLine());
				logger.error("postStatusCode:" + statusCode);
				logger.error("postUrl:" + url);
				logger.error("postBody:" + jsonRequest);
			}
			
			// Read the response body
			body = EntityUtils.toString(response.getEntity(), "UTF-8");
		} catch (IOException e) {
			e.printStackTrace();
			logger.error("PostJsonException: "+url+" jsonBody:"+jsonRequest);
		}		

		return body;
	}
	
	
    /**
     * zls
     * 上传差分包文件
     * @param url
     * @param string
     * @return
     * @throws IOException 
     */
	@SuppressWarnings({ "rawtypes" })
	public static String sendPostFile(String url, String filezd,String filepath,String jsonrequest) throws IOException {
		String key="";
		String value="";
		HttpPost httppost = new HttpPost(url);
		File file=null;
		if(!(filepath.equals("")))
		{
		file=new File(filepath);
		FileBody binFileBody =null;
		binFileBody = new FileBody(file); 
		MultipartEntityBuilder multipartEntityBuilder=null;
		multipartEntityBuilder = MultipartEntityBuilder.create();  
		multipartEntityBuilder.setCharset(Charset.forName("UTf-8"));
		
		JSONObject jsonObj =null;
		jsonObj = JSONObject.fromObject(jsonrequest);  
		//logger.info("打印文件======"+jsonObj.getString("logFiles"));
	
		//StringBuffer sbu = new StringBuffer();
		Iterator it=(Iterator) jsonObj.keys();
		while (it.hasNext()) {
			key = (String) it.next();
			value=jsonObj.getString(key).toString();
			multipartEntityBuilder.addTextBody(key, value, ContentType.create("text/plain", Charset.forName("UTF-8")));  
        }  
	
		 //multipartEntityBuilder.addPart("file", binFileBody);  
		 multipartEntityBuilder.addPart(filezd, binFileBody);  
		 HttpEntity reqEntity=null;
		 reqEntity = multipartEntityBuilder.build();  
	     httppost.setEntity(reqEntity); 
		}
        CloseableHttpResponse response = null; 
		try {
			response=getHttpClient().execute(httppost); ;
		} catch (IOException e) {
			e.printStackTrace();
		}
		HttpEntity entity1 = response.getEntity();
		String result = null;
		try {
			result = EntityUtils.toString(entity1);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	
	
	
	
	
	
	
	
	
	/**
	 * ����httpclient���ӳأ�����ʼ��httpclient
	 */
	public void initHttpClient() {
		// ����httpclient���ӳ�
		httpClientConnectionManager = new PoolingHttpClientConnectionManager();
		// �������ӳ��������
		httpClientConnectionManager.setMaxTotal(HTTPCLIENT_CONNECTION_COUNT);
		// ���õ���·�������������
		httpClientConnectionManager.setDefaultMaxPerRoute(HTTPCLIENT_MAXPERROUTE_COUNT);
	}

	// �������Ի���
	static HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
		public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
			if (executionCount >= 3) {
				// ��������������������
				return false;
			}
			if (exception instanceof Exception) {
				return false;
			}
			HttpClientContext clientContext = HttpClientContext.adapt(context);
			HttpRequest request = clientContext.getRequest();
			boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
			if (idempotent) {
				// Retry if the request is considered idempotent
				return true;
			}
			return false;
		}
	};

	/**
	 * 
	 * ��������getHttpClient ���������̵߳���ʱ����Ҫ�����Լ���httpclient
	 * 
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static CloseableHttpClient getHttpClient() {
		// ����ȫ�ֵ�requestConfig
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(HTTPCLIENT_CONNECT_TIMEOUT)
				.setSocketTimeout(HTTPCLIENT_SOCKET_TIMEOUT).setCookieSpec(CookieSpecs.BEST_MATCH).build();
		// �����ض�����Զ���
		LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();

		CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(httpClientConnectionManager)
				.setDefaultRequestConfig(requestConfig).setRedirectStrategy(redirectStrategy)
				.setRetryHandler(myRetryHandler).build();

		return httpClient;
	}

	/**
	 * 
	 * ��������createSSLClientDefault ���������https����SSL�ķ�ʽ����httpclient
	 * 
	 * @return
	 */
	public static CloseableHttpClient createSSLClientDefault() {
		try {
			SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
				// ��������
				public boolean isTrusted(X509Certificate[] chain, String authType) {
					return true;
				}
			}).build();

			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);

			return HttpClients.custom().setSSLSocketFactory(sslsf).build();

		} catch (Exception e) {
			e.printStackTrace();
		}

		return HttpClients.createDefault();
	}
	
	
	
	

	
	
	
	

	/**
	 * ����HttpGet����
	 * 
	 * @param url
	 * @return
	 */
	// public static String sendGet(String url) {
	// HttpGet httpget = new HttpGet(url);
	// CloseableHttpResponse response = null;
	// try {
	// response = getHttpClient().execute(httpget);
	// } catch (IOException e1) {
	// e1.printStackTrace();
	// }
	// String result = null;
	// try {
	// HttpEntity entity = response.getEntity();
	// if (entity != null) {
	// result = EntityUtils.toString(entity);
	// }
	// } catch (Exception e) {
	// e.printStackTrace();
	// } finally {
	// try {
	// response.close();
	// } catch (IOException e) {
	// e.printStackTrace();
	// }
	// }
	//
	// return result;
	// }

	/**
	 * ����HttpPost���󣬲���Ϊmap
	 * 
	 * @param url
	 * @param map
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	// public static String sendPost(String url, Map<String, String> map)
	// throws UnsupportedEncodingException {
	// List<NameValuePair> formparams = new ArrayList<NameValuePair>();
	//
	// for (Map.Entry<String, String> entry : map.entrySet()) {
	// formparams.add(new BasicNameValuePair(entry.getKey(), entry
	// .getValue()));
	// }
	//
	// UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams,
	// "utf-8");
	// HttpPost httppost = new HttpPost(url);
	// httppost.setEntity(entity);
	// // entity.setContentType(ctString);
	// CloseableHttpResponse response = null;
	//
	// try {
	// response = getHttpClient().execute(httppost);
	// } catch (IOException e) {
	// e.printStackTrace();
	// }
	//
	// HttpEntity entity1 = response.getEntity();
	// String result = null;
	// try {
	// result = EntityUtils.toString(entity1);
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	//
	// return result;
	// }

	/**
	 * ���Ͳ���������HttpPost����
	 * 
	 * @param url
	 * @return
	 */
	// public static String sendPost(String url) {
	// HttpPost httppost = new HttpPost(url);
	// CloseableHttpResponse response = null;
	// try {
	// response = getHttpClient().execute(httppost);
	// } catch (IOException e) {
	// e.printStackTrace();
	// }
	// HttpEntity entity = response.getEntity();
	// String result = null;
	// try {
	// result = EntityUtils.toString(entity);
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// return result;
	// }

	@SuppressWarnings("unused")
	/**
	 * ��ȡ����ı���
	 * 
	 * @param inputStream
	 * @return
	 * @throws IOException
	 */
	private String getRequestXml(InputStream inputStream) throws IOException {
		StringBuffer requestXml = new StringBuffer();
		byte[] b = new byte[2048];
		int length = 0;
		while ((length = inputStream.read(b)) != -1) {
			requestXml.append(new String(b, 0, length));
		}

		return requestXml.toString();
	}

	/**
	 * 
	 * ������ı���ת��ΪMap����
	 * 
	 * @param xmlStr
	 * @return
	 */
	// private Map<String, Object> convertXmlToMap(String xmlStr) {
	// Map<String, Object> params = new HashMap<String, Object>();
	// return params;
	// }

	/**
	 * post the json request.
	 * 
	 * @param url
	 * @param jsonRequest
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static HttpResponse post(final String url, final String xmlRequest) {
		// ����һ��NameValuePair���飬���ڴ洢�����͵Ĳ���
		HttpPost post = new HttpPost(url);
		post.addHeader("Content-Type", "application/vnd.syncml.dm+xml");
		post.setEntity(new StringEntity(xmlRequest, Charset.forName("UTF-8")));
		HttpResponse response = null;
//		System.out.println("httpRequest888");
		try {
			response = getHttpClient().execute(post);
		} catch (IOException e) {
			System.out.println("e:" + e.getStackTrace());

		}
//		System.out.println("httpResponse888");
		return response;
	}

	public static JSONObject doJsonPost(String url, JSONObject json) {

		CloseableHttpClient httpclient = HttpClientBuilder.create().build();
		HttpPost post = new HttpPost(url);
		JSONObject response = null;
		try {
			StringEntity s = new StringEntity(json.toString());
			s.setContentEncoding("UTF-8");
			s.setContentType("application/json");// 发送json数据需要设置contentType
			post.setEntity(s);
			HttpResponse res = httpclient.execute(post);
			if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				String result = EntityUtils.toString(res.getEntity());// 返回json格式：
				response = JSONObject.fromObject(result);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return response;
	}

}
